﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;

namespace PesticideManage.API.Services.JWT.Extensions.DependencyInjection;

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddJwtBearerAuthentication(this IServiceCollection services, IConfiguration configuration)
    {
        services.AddDistributedMemoryCache();
        services.Configure<JwtOptions>(configuration.GetSection(JwtOptions.Name));

        var jwtOptions = configuration.GetSection(JwtOptions.Name).Get<JwtOptions>() ?? throw new NullReferenceException();

        services.AddSingleton(sp => new SigningCredentials(jwtOptions.SymmetricSecurityKey, SecurityAlgorithms.HmacSha256Signature));

        services.AddScoped<AppJwtBearerEvents>();

        services.AddScoped<IAuthTokenService, AuthTokenService>();

        var tokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,  //是否验证发行者 Issuer
            ValidIssuer = jwtOptions.Issuer,
            ValidateAudience = true,//是否验证受众 Audience
            ValidAudience = jwtOptions.Audience,

            // 是否验证SecurityKey
            ValidateIssuerSigningKey = true,
            // 拿到SecurityKey        
            IssuerSigningKey = jwtOptions.SymmetricSecurityKey,
            //是否验证失效时间
            ValidateLifetime = true,
            // 初始过期时间,默认5分钟
            // ClockSkew = TimeSpan.FromSeconds(10),
        };

        services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options =>
            {
                options.SaveToken = true;
                options.TokenValidationParameters = tokenValidationParameters;
                options.EventsType = typeof(AppJwtBearerEvents);
                //options.Events = new JwtBearerEvents()
                //{
                //    OnAuthenticationFailed = context =>
                //    {
                //        if (context.Exception is SecurityTokenExpiredException)
                //        {
                //            context.Response.Headers.Add("Expires", "expired");
                //        }
                //        return Task.CompletedTask;
                //    }
                //};
            });
        return services;
    }
}
